#include <QtGui>
#include <PopupSettings.hpp>
#include <PopupMessageDialog.hpp>
#include <PopupVersion.hpp>
#include <PopupUtilities.hpp>

using namespace std;
using namespace Popup;

#include "PopupUsersWidget.hpp"
#include "PopupMessageWidget.hpp"

#define CONNECTING_STRING "Connecting..."

//==============================================================================
// Construction/Destruction
//==============================================================================

PopupMessageDialog::PopupMessageDialog(QWidget*)
 : m_mainWidget(new PopupMessageWidget(this)),
   m_moving(false), m_notificationDlg(this)
{
  setupUi(this);
  slot_applyNewSettings();

#if QT_VERSION >= 0x040500
  setAttribute(Qt::WA_TranslucentBackground, true);
#endif
  
  QRect _rect = QApplication::desktop()->availableGeometry();
  int _xpos = _rect.width() - width() - 40;
  int _ypos = 45;
  move(_xpos, _ypos);

  // Setup popup version string and hide popup user edit
  m_versionLabel->setText("Popup v" +
      QString::number((double)PopupBuildInfo::version(), 'f', 2));
  m_userNicknameEdit->setVisible(false);

  // Insert tabbed widget
  m_layout->insertWidget(1, m_mainWidget);

  // Hide all record flags
  m_likeRecord->setVisible(false);
  m_dontLikeRecord->setVisible(false);
  m_poetryRecord->setVisible(false);
  m_fuckRecord->setVisible(false);

  // Close shortcut
  QAction *_closeAction = new QAction(tr("&Close"), this);
  _closeAction->setShortcut(tr("Escape"));
  _closeAction->setShortcutContext(Qt::WidgetWithChildrenShortcut);
  addAction(_closeAction);
  connect(_closeAction, SIGNAL(triggered()), this, SLOT(hide()));

  connect(m_setupBtn, SIGNAL(clicked()), this, SLOT(slot_showSomeDialog()));
  connect(m_loginBtn, SIGNAL(clicked()), this, SLOT(slot_showSomeDialog()));
  connect(m_logsBtn, SIGNAL(clicked()), this, SLOT(slot_showSomeDialog()));
  connect(m_userNicknameEdit, SIGNAL(returnPressed()),
          this, SLOT(slot_nicknameUpdated()));
  connect(m_avatarButton, SIGNAL(clicked()), this, SLOT(slot_browseAvatar()));
  connect(m_modeButton, SIGNAL(clicked()), this, SLOT(slot_browseMode()));
  connect(&m_notificationDlg, SIGNAL(signal_timeout()),
          this, SLOT(slot_onRequestUserChangeTimeout()));

  // Register to users manager
  PopupUsersManager::instance()->registerObserver(this);
}

//==============================================================================
// Slots
//==============================================================================

void PopupMessageDialog::slot_nicknameUpdated()
{
  string _newvalue = m_userNicknameEdit->text().toStdString();
  if (_newvalue.compare(getNickname()) != 0) {
    // Restore previous nickname user update request is sent to server
    m_userNicknameEdit->setText(getNickname().c_str());
    setNickname(_newvalue);
    // Show request notification
    m_notificationDlg.show("Sending nickname request update to server...", 5000);
  }
}

void PopupMessageDialog::slot_browseAvatar()
{
  if (m_topLabel->text() != CONNECTING_STRING)
  {
    QString _default = "";
    QString _avatar = getAvatar().c_str();
    if (QFile(_avatar).exists()) {
      _default = _avatar;
    }

    QString _fileName =
        QFileDialog::getOpenFileName(this, tr("Please choose you avatar"),
                                     _default,tr("Image files (*)"));
    if (!_fileName.isEmpty()) {
      setAvatar(_fileName.toStdString());
      m_notificationDlg.show("Sending avatar change request to server...", 5000);
    }
  }
}

void PopupMessageDialog::slot_browseMode()
{
  if (m_topLabel->text() != CONNECTING_STRING)
  {
    Popup::UserMode _mode;
    // Shift to next mode
    _mode = getNextMode(PopupSettings::instance()->defaultClientMode());

    // Save settings
    PopupSettings::instance()->setDefaultClientMode(_mode);
    PopupSettings::instance()->serialize(PopupSettings::POPUP_SAVE_TO_FILE);

    // Let everybody know about our new status
    setMode(_mode);
  }
}

void PopupMessageDialog::slot_onRequestUserChangeTimeout()
{
  utilities::showError("Failed!");
}


void PopupMessageDialog::localUserUpdated(unsigned short p_updateMask)
{
  if (p_updateMask & POPUP_USER_FIELD_NICKNAME) {
    QString _newNickname = QString::fromUtf8(getNickname().c_str());
    m_topLabel->setText(_newNickname);
    m_userNicknameEdit->setText(_newNickname);
  }
  if (p_updateMask & POPUP_USER_FIELD_AVATAR) {
    QIcon _icon;
    _icon.addFile(QString::fromUtf8(getAvatar().c_str()), QSize(48,48));
    m_avatarButton->setIcon(_icon);
  }
  if (p_updateMask & POPUP_USER_FIELD_MODE) {
    QIcon _icon;
    getIconFromMode(_icon,PopupSettings::instance()->defaultClientMode());
    m_modeButton->setIcon(_icon);
  }
}

void PopupMessageDialog::userUpdated(const PopupUserExt *p_user,
                                     unsigned short p_updateMask,
                                     bool)
{
  if (p_user->getID() == getMyID()) {
    if (p_updateMask & POPUP_USER_FIELD_NICKNAME) {
      m_notificationDlg.hide();
      QString _newNickname = QString::fromUtf8(p_user->getNickname().c_str());
      m_topLabel->setText(_newNickname);
      m_userNicknameEdit->setText(_newNickname);
    }
    if (p_updateMask & POPUP_USER_FIELD_AVATAR) {
      m_notificationDlg.hide();
      QIcon _icon;
      _icon.addFile(QString::fromUtf8(getAvatar().c_str()), QSize(48,48));
      m_avatarButton->setIcon(_icon);
    }
    if (p_updateMask & POPUP_USER_FIELD_MODE) {
      m_notificationDlg.hide();
      QIcon _icon;
      getIconFromMode(_icon,PopupSettings::instance()->defaultClientMode());
      m_modeButton->setIcon(_icon);
    }
 }
}

void PopupMessageDialog::userStatisticsUpdated(const PopupUserExt *p_user,
                                               unsigned short p_updateMask)
{
  unsigned int _value = 0;
  bool _isRecord = false;

  if (p_user->getID() == getMyID()) {
    if ((p_updateMask & POPUP_RATE_LIKE) &&
        p_user->stats.get(POPUP_RATE_LIKE, _value, _isRecord)) {
        m_nbLike->setText(QString::number(_value, 10));
        m_likeRecord->setVisible(_isRecord);
    }
    if ((p_updateMask & POPUP_RATE_DONTLIKE) &&
        p_user->stats.get(POPUP_RATE_DONTLIKE, _value, _isRecord)) {
      m_nbDontLike->setText(QString::number(_value, 10));
      m_dontLikeRecord->setVisible(_isRecord);

    }
    if ((p_updateMask & POPUP_RATE_POETRY) &&
        p_user->stats.get(POPUP_RATE_POETRY, _value, _isRecord)) {
      m_nbPoetry->setText(QString::number(_value, 10));
      m_poetryRecord->setVisible(_isRecord);

    }
    if ((p_updateMask & POPUP_RATE_FUCKYOU) &&
        p_user->stats.get(POPUP_RATE_FUCKYOU, _value, _isRecord)) {
      m_nbFuck->setText(QString::number(_value, 10));
      m_fuckRecord->setVisible(_isRecord);
    }
  }
}

//==============================================================================
// Slots
//==============================================================================

void PopupMessageDialog::slot_applyNewSettings()
{
  bool _visible = isVisible();

  if (PopupSettings::instance()->framelessMessageDialog()) {
    setWindowFlags(Qt::FramelessWindowHint|Qt::WindowStaysOnTopHint);
  } else {
    Qt::WindowFlags flags = windowFlags();
    flags = (flags & ~(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint));
    setWindowFlags(flags);
  }

  setStyleSheet(PopupSettings::instance()->messageDialogStyleSheet());
  if (_visible) setVisible(true);

  // Notify sub widget
  m_mainWidget->slot_applyNewSettings();
}

void PopupMessageDialog::slot_onConnectionUpdate(bool p_connected)
{
  m_mainWidget->setEnabled(p_connected);
  if (p_connected) {
    QString _nickname = getNickname().c_str();
    m_topLabel->setText(_nickname);
    m_userNicknameEdit->setText(_nickname);
  } else  {
    m_topLabel->setText(CONNECTING_STRING);
  }
}

void PopupMessageDialog::slot_showSomeDialog()
{
  QObject *_emitter = QObject::sender();
  if (_emitter == (QObject*) m_setupBtn) {
    emit signal_showDialog(PopupGui::POPUP_DIALOG_ID_SETTINGS);
  } else if (_emitter == (QObject*) m_loginBtn) {
    emit signal_showDialog(PopupGui::POPUP_DIALOG_ID_LOGIN);
  } else if (_emitter == (QObject*) m_logsBtn) {
    emit signal_showDialog(PopupGui::POPUP_DIALOG_ID_LOGS);
  }
}

//==============================================================================
// QT standard callbacks overriding
//==============================================================================

void PopupMessageDialog::mousePressEvent(QMouseEvent *event)
{
  if (event->button() == Qt::LeftButton) {
    event->accept();
    if (!m_moving) {
      m_moving = true;
      m_offsetInWidget = mapFromGlobal(event->globalPos());
    }
  }
}
//----------------------------------------------------------

void PopupMessageDialog::mouseReleaseEvent(QMouseEvent *event)
{
  if (event->button() == Qt::LeftButton) {
    event->accept();
    m_moving = false;
  }
}
//----------------------------------------------------------

void PopupMessageDialog::mouseMoveEvent(QMouseEvent *event)
{
  if (event->buttons() & Qt::LeftButton) {
    move(event->globalPos() - m_offsetInWidget);
    event->accept();
  }
}
//----------------------------------------------------------

void PopupMessageDialog::mouseDoubleClickEvent(QMouseEvent *)
{
  if (m_topLabel->underMouse() &&
      (m_topLabel->text() != CONNECTING_STRING))
  {
    m_userNicknameEdit->setVisible(true);
    m_topLabel->setVisible(false);
    m_userNicknameEdit->selectAll();
    m_userNicknameEdit->setFocus();
  }
}

void PopupMessageDialog::getThreadWidgets(
    vector<const PopupThreadWidget*> & p_widgets) const
{
  m_mainWidget->getThreadWidgets(p_widgets);
}

void PopupMessageDialog::slot_restoreThread(const PopupGui::PopupThreadSave & p_saved)
{
  m_mainWidget->addThread(p_saved);
}

